/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

import * as vscode from 'vscode';
import * as path from 'path';
import testAssetWorkspace from './testAssets/testAssetWorkspace';
import {
    activateCSharpExtension,
    closeAllEditorsAsync,
    navigate,
    openFileInWorkspaceAsync,
    sleep,
    sortLocations,
} from './integrationHelpers';
import { beforeAll, beforeEach, afterAll, test, expect, afterEach, describe } from '@jest/globals';

describe(`Source Generator Tests`, () => {
    beforeAll(async () => {
        await activateCSharpExtension();
    });

    beforeEach(async () => {
        await openFileInWorkspaceAsync(path.join('src', 'app', 'SourceGenerator.cs'));

        // Unfortunately, due to the way source generators work we will not necessarily have the source generated files
        // as soon as the project finishes loading.  It may be using a partial compilation which has not run generators yet.
        // So we have to wait here for a bit to ensure the source generated files are available.
        // Once we have enabled balanced mode in the extension, we will have an explicit command to run generators which
        // we can use here to force the generation instead of waiting.
        // See https://github.com/dotnet/roslyn/issues/75152
        await sleep(5000);
    });

    afterAll(async () => {
        await testAssetWorkspace.cleanupWorkspace();
    });

    afterEach(async () => {
        await closeAllEditorsAsync();
    });

    test('Navigates to reference in source generated file', async () => {
        const requestPosition = new vscode.Position(14, 25);
        const referencesList = <vscode.Location[]>(
            await vscode.commands.executeCommand(
                'vscode.executeReferenceProvider',
                vscode.window.activeTextEditor!.document.uri,
                requestPosition
            )
        );
        expect(referencesList.length).toEqual(5);
        const referencesInGeneratedFiles = sortLocations(
            referencesList.filter((r) => r.uri.scheme === 'roslyn-source-generated')
        );
        expect(referencesInGeneratedFiles.length).toEqual(4);
        const firstPath = referencesInGeneratedFiles[0].uri.path;
        expect(firstPath).toEqual('/SourceGenerationContext.g.cs');

        await navigate(requestPosition, referencesInGeneratedFiles, 'SourceGenerationContext.g.cs');
        expect(vscode.window.activeTextEditor?.document.getText()).toContain('// <auto-generated/>');
        expect(vscode.window.activeTextEditor?.document.getText()).toContain(
            'internal partial class SourceGenerationContext'
        );
    });
});
